package reflect;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Scanner;

/**
 * java的反射机制:
 * 反射是java的动态机制, 允许程序再[运行期间]再决定如对象实例化, 属性操作, 方法调用等.
 * 可以提高代码的灵活性, 扩展性, 维护性
 * 但运行效率相对降低, 同时开销会增多
 * 需要适度使用
 */
public class ReflectDemo1 {
    public static void main(String[] args) throws ClassNotFoundException {
        /*
         * 反射机制的第一步: 获取要操作的类的Class对象
         * java.lang.Class(类对象)
         * 它的每一个实例用于表示一个被JVM加载的类, 意味着JVM每加载一个类的同时就会实例化一个Class对象与之绑定
         * 并在该Class实力上记录加载的类的一切信息, 通过Class可以了解这个类的所有信息
         */

        /**
         * 获取类对象的三种方式:
         */
        /*
        //第一种: 数据类型.class
        Class cls = String.class; // 获取String的类对象
        Class cls2 = ArrayList.class; // 获取ArrayList的类对象
        Class cls3 = int.class; // 获取int的类对象

        //第二种: 通过指令累的完全限定名获取一个类的类对象, Class.forName(String className), 该方法需要处理异常, 可以用try/catch捕获, 或者抛出去
        Class cls4 = Class.forName("java.lang.String"); // 获取String的类对象
        Class cls5 = Class.forName("java.util.ArrayList"); //
        // Class cls6 = Class.forName("int"); //运行报错, 运行报错, 因为int不是类, 而是基本数据类型, 基本数据类型需要.class来获取

        //第三种: 通过扫描器扫描输入获取一个类的类对象, 此种方式的底层逻辑同第二种
        Scanner sc = new Scanner(System.in);// 创建一个扫描器
        System.out.println("请输入一个类名: ");// 提示用户输入
        String Name = sc.nextLine(); // 获取用户输入
        Class cls7 = Class.forName(Name); // 获取用户输入的类的类对象
         */

        Scanner sc = new Scanner(System.in);// 创建一个扫描器
        System.out.println("请输入一个类名: ");// 提示用户输入
        String name = sc.nextLine();
        Class cls = Class.forName(name);//基于类名构造Class类对象

        cls.getName();//得到完整的类名
        //cls.getSimpleName(); // 得到简单的类名
        System.out.println("获取类的完全限定名"+cls.getName());
        System.out.println("获取类的简单名"+cls.getSimpleName());
        /*
         * Class的每个实例用于表示一个类
         * Package是反射对象之一, 它的每个实例用于表示一个包
         */
        Package pkg = cls.getPackage();//得到包对象
        System.out.println("获取包名"+pkg.getName());

        /*
         * Method是反射对象之一, 它的每个实例用于表示一个方法
         */
        Method[] methods = cls.getMethods();//获取所有方法
        System.out.println("一共"+methods.length+"个方法");
        for (Method method : methods){//遍历所有方法
            System.out.println(method.getName());//获取方法名
        }


    }

}
